# -*- coding: UTF-8 -*-
import datetime
import time
from typing import Union


def get_time(source: Union[int, str, datetime.datetime] = "now", out_format="datetime", out_type="dt"):
    """
    尝试获取任何类型格式的时间，并输出任何类型格式的时间
    :param source:
    :param out_format: "datetime" | "date" | "time" | "timestamp"
    :param out_type: int | str | dt
    :return:
    """
    if source == "now":
        dt = datetime.datetime.now()
    elif isinstance(source, (int, float)) or str(source).split(".")[0].isdigit():
        # todo 这里会有精度缺失的问题
        dt = datetime.datetime.fromtimestamp(int(source))
    elif isinstance(source, datetime.datetime):
        d = source.date()
        t = source.time()
        dt = datetime.datetime(year=d.year, month=d.month, day=d.day, hour=t.hour, minute=t.minute, second=t.second)
    elif isinstance(source, datetime.date):
        d = source.today()
        t = datetime.datetime.now().time()
        dt = datetime.datetime(year=d.year, month=d.month, day=d.day, hour=t.hour, minute=t.minute, second=t.second)
    elif isinstance(source, datetime.time):
        d = datetime.datetime.now().date()
        t = source
        dt = datetime.datetime(year=d.year, month=d.month, day=d.day, hour=t.hour, minute=t.minute, second=t.second)
    else:
        d = datetime.datetime.strptime(source, "%Y-%m-%d") if len(source.split("-")) == 3 else ""
        t = datetime.datetime.strptime(source, "%H:%M:%S") if len(source.split(":")) >= 3 else ""
        dt = datetime.datetime(year=d.year, month=d.month, day=d.day, hour=t.hour, minute=t.minute, second=t.second)

    return out_time(dt, out_format, out_type, source=source)


def out_time(dt: datetime.datetime, out_format="datetime", out_type="dt", **kwargs):
    """
    将时间转化为指定格式输出
    :param dt: datetime
    :param out_format: "datetime" | "date" | "time" | "timestamp"
    :param out_type: int | str | dt
    :param kwargs: 附带的字段，无实际意义，本函数中仅为日志输出
    :return:
    """
    if out_type == "int" and out_format == "timestamp":
        tp = dt.timetuple()
        return int(time.mktime(tp))
    elif out_type == "str":
        if out_format == "time":
            return datetime.date.strftime(dt, "%H:%M:%S")
        elif out_format == "date":
            return datetime.date.strftime(dt, "%Y-%m-%d")
        elif out_format == "datetime":
            return datetime.date.strftime(dt, "%Y-%m-%d %H:%M:%S")
    elif out_type == "dt":
        if out_format == "time":
            return dt.time()
        elif out_format == "date":
            return dt.date()
        elif out_format == "datetime":
            return dt

    raise TypeError(f"暂不支持此格式转化，source: {kwargs.get('source')}, out_format: {out_format}, out_type: {out_type}")


def time_window(source: Union[int, str, datetime.datetime] = "now", window_type: str = "+", **kwargs):
    """
    时间拼接并返回指定格式
    :param window_type: 时间改变的类型，或增或减
    :param source: datetime
    :param kwargs: timedelta 的参数
    :return:
    """
    source = datetime.datetime.now() if source == "now" else get_time(source)
    if window_type == "+":
        dt = source + datetime.timedelta(**kwargs)
    else:
        dt = source - datetime.timedelta(**kwargs)
    return out_time(dt, out_type="str", out_format="datetime")


if __name__ == "__main__":
    now = datetime.datetime.now()
    a = get_time(source=now, out_format="timestamp", out_type="int")
    print(a)
    print(type(a))

